package v1

import (
	"encoding/json"
	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
	"github.com/pkg/errors"
	"io/ioutil"
	"net/http"
	"strconv"
	"zimuzu_cvn_web_api/config"
	"zimuzu_cvn_web_api/model"
	"zimuzu_cvn_web_api/pkg/e"
	"zimuzu_cvn_web_api/pkg/errno"
	"zimuzu_cvn_web_api/router/api"
	"zimuzu_cvn_web_api/router/api/web/middleware"
	"zimuzu_cvn_web_api/service"
)

type IndexAPI struct {
}

func (index IndexAPI) Name() string {
	return "index API"
}

func (index IndexAPI) Bind() {
	indexAPI := config.C.Router.Group("/v1/index", middleware.TrackLog())
	{
		indexAPI.GET("slideshow", slideShow)
		indexAPI.GET("slideshowClick", slideShowClick)
	}

	miningAPI := config.C.Router.Group("/v1/mining", middleware.TrackLog())
	{
		miningAPI.GET("daylyInfo", daylyInfo)
		miningAPI.GET("amountInfo", amountInfo)
	}

	cvntAPI := config.C.Router.Group("/v1/cvnt", middleware.TrackLog())
	{
		cvntAPI.GET("price", cvntPirce)
	}
}

type slideShowResponse struct {
	CycleTime int               `json:"cycleTime"`
	Images    []model.Slideshow `json:"imgs"`
}

//slideShow 获取轮播图
//Auth: Xu
func slideShow(c *gin.Context) {
	slideShowList, err := service.GetSlideshow(model.IndexSlideshowModule)
	if err != nil {
		api.SendResponse(c, err, slideShowList)
		return
	}
	slideShowResponseData := slideShowResponse{
		CycleTime: service.SlideshowCycleTime,
		Images:    slideShowList,
	}
	errno.OK.Info = "操作成功"
	api.SendResponse(c, errno.OK, &slideShowResponseData)
	return
}

type slideShowClickParams struct {
	ID int `form:"id" json:"id" binding:"required"`
}

//slideShowClick 轮播图点击
//Auth: Xu
func slideShowClick(c *gin.Context) {
	var params slideShowClickParams
	err := c.ShouldBindWith(&params, binding.Query)
	if err != nil {
		api.SendResponse(c, err, nil)
		return
	}

	service.SlideShowClickStatistics(params.ID)
	errno.OK.Info = "操作成功"
	api.SendResponse(c, errno.OK, "")
	return
}

type daylyInfoResponse struct {
	All      *service.RouterUploadInfoStr `json:"all"`
	Personal *service.RouterUploadInfoStr `json:"personal, omitempty"`
	Linux    struct {
		TotalNodeCount int   `json:"totalNodeCount"`
		TotalUpload    int64 `json:"totalUpload"`
	} `json:"linux"`
	Router struct {
		SaleAmount   int    `json:"saleAmount"`
		MiningAmount int    `json:"miningAmount"`
		Up           string `json:"up"`
	} `json:"router"`
}

//daylyInfo 挖矿日常统计信息
//Auth: Xu
func daylyInfo(c *gin.Context) {
	//获取全网上传量信息
	netTotalUpload, err := service.GetNetTotalUpload()
	if err != nil {
		api.SendResponse(c, errors.New("查询挖矿统计信息失败"), nil)
		return
	}

	//获取全网路由器贡献流量
	oldUp, err := model.GetRouterOldUpload(0)
	if err != nil {
		api.SendResponse(c, errors.New("查询挖矿统计信息失败"), nil)
		return
	}
	newUp, err := model.GetUserTotalUpload(0, model.NodeTypeRouter)
	if err != nil {
		api.SendResponse(c, errors.New("查询挖矿统计信息失败"), nil)
		return
	}

	millInfo := service.GetNetMillInfo()
	responseData := daylyInfoResponse{
		All: &netTotalUpload,
		Linux: struct {
			TotalNodeCount int   `json:"totalNodeCount"`
			TotalUpload    int64 `json:"totalUpload"`
		}{TotalNodeCount: millInfo.TotalNodeCount, TotalUpload: millInfo.TotalUpload},
		Router: struct {
			SaleAmount   int    `json:"saleAmount"`
			MiningAmount int    `json:"miningAmount"`
			Up           string `json:"up"`
		}{SaleAmount: millInfo.SaleAmount, MiningAmount: millInfo.MiningAmount, Up: e.SizeFormat((oldUp+newUp)*1024, 2)},
	}
	if checkLoginErr := middleware.CheckTokenLogin(c); checkLoginErr == nil {
		uid, _ := service.GetUserIdByRequest(c)
		routerUploadInfo, _ := service.GetPersonalRouterMiningInfo(uid)
		routerUploadInfo.MineAmount = service.CalculateUserToadyCvnt(routerUploadInfo.TotalContribute, netTotalUpload.TotalContribute)

		responseData.Personal = &routerUploadInfo
	}

	errno.OK.Info = "操作成功"
	api.SendResponse(c, errno.OK, responseData)
	return
}

type cvntPriceResponseData struct {
	Status int    `json:"status"`
	Info   string `json:"info"`
	Data   struct {
		ETH     cvntPrice `json:"eth,omitempty"`
		BTC     cvntPrice `json:"btc,omitempty"`
		ETHUsdt cvntPrice `json:"ethBase,omitempty"`
		BTCUsdt cvntPrice `json:"btcBase,omitempty"`
	} `json:"data,omitempty"`
}
type cvntPrice struct {
	Change    float64     `json:"change"`
	Price     interface{} `json:"price"`
	UsdPrice  float64     `json:"usdPrice"`
	CnyPrice  float64     `json:"cnyPrice"`
	DayVloume float64     `json:"volume"`
}

//获取cvnt价格信息
func cvntPirce(c *gin.Context) {
	httpurl := config.C.JapenUrl + "/v1/market/getCvntPrice"
	responseData := cvntPriceResponseData{}
	resp, err := http.Get(httpurl)
	if err != nil {
		api.SendResponse(c, errors.New("请求失败"+err.Error()), nil)
		return
	}
	defer resp.Body.Close()
	body, _ := ioutil.ReadAll(resp.Body)
	json.Unmarshal(body, &responseData)
	responseData.Data.BTC.Price = strconv.FormatFloat(responseData.Data.BTC.Price.(float64), 'f', 8, 64)

	errno.OK.Info = "操作成功"
	api.SendResponse(c, errno.OK, responseData.Data)
	return
}

type amountInfoParams struct {
	Linux struct {
		TotalNodeCount int   `json:"totalNodeCount"`
		TotalUpload    int64 `json:"totalUpload"`
	} `json:"linux"`
	Router struct {
		SaleAmount   int `json:"saleAmount"`
		MiningAmount int `json:"miningAmount"`
	} `json:"router"`
}

//linux节点及路由器信息
func amountInfo(c *gin.Context) {
	millInfo := service.GetNetMillInfo()
	amountInfoParams := amountInfoParams{
		Linux: struct {
			TotalNodeCount int   `json:"totalNodeCount"`
			TotalUpload    int64 `json:"totalUpload"`
		}{TotalNodeCount: millInfo.TotalNodeCount, TotalUpload: millInfo.TotalUpload},
		Router: struct {
			SaleAmount   int `json:"saleAmount"`
			MiningAmount int `json:"miningAmount"`
		}{SaleAmount: millInfo.SaleAmount, MiningAmount: millInfo.MiningAmount},
	}

	errno.OK.Info = "获取数据成功"
	api.SendResponse(c, errno.OK, amountInfoParams)
	return
}
